package mongodb;

import com.mongodb.Block;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Updates.*;

import com.mongodb.client.model.Aggregates;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.changestream.ChangeStreamDocument;
import com.mongodb.client.model.changestream.FullDocument;
import com.mongodb.client.result.UpdateResult;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.bson.Document;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class Mongodb {
    public static void main(String[] args) {

        //Create a connection and get a collection
        MongoClient mongoClient = new MongoClient("localhost", 27017);
        MongoDatabase mongoDatabase = mongoClient.getDatabase("test");
        //MongoCollection<Document> mongoCollection=mongoDatabase.getCollection("demo");



        //combine the default codec registry,with the PojoCodecProvider configured to automatically create PojoCodecs

        /**
         * 官方实例
         * mongodb.Person pojo to BSON
         */

        /**
         MongoCollection<mongodb.Person> mongoCollection=mongoDatabase.getCollection("demo",mongodb.Person.class);
         CodecRegistry pojoCodecRegistry= CodecRegistries.fromRegistries(mongoClient.getDefaultCodecRegistry(),
         CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build()));

        mongoCollection=mongoCollection.withCodecRegistry(pojoCodecRegistry);

        mongodb.Person ada=new mongodb.Person("Ada Byron",20,new mongodb.Address("St James Square","London","W1"));
        mongoCollection.insertOne(ada);

        List<mongodb.Person> people = Arrays.asList(
                new mongodb.Person("Charles Babbage", 45, new mongodb.Address("5 Devonshire Street", "London", "W11")),
                new mongodb.Person("Alan Turing", 28, new mongodb.Address("Bletchley Hall", "Bletchley Park", "MK12")),
                new mongodb.Person("Timothy Berners-Lee", 61, new mongodb.Address("Colehill", "Wimborne", null))
        );
        mongoCollection.insertMany(people);
        Block<mongodb.Person> printBlock =new Block<mongodb.Person>() {
            public void apply(mongodb.Person person) {
                System.out.println(person);
            }
        };
        mongoCollection.find().forEach(printBlock);
        mongodb.Person somebody=mongoCollection.find(Filters.eq("address.city","Wimborne")).first();
        System.out.println(somebody);
*/

        /**
         * BLOG mongodb.Article pojo to bson
         */

        MongoCollection<Document> collection=mongoDatabase.getCollection("article");
        MongoCollection<Article> mongoCollection=mongoDatabase.getCollection("article",Article.class);
        CodecRegistry pojoCodecRegistry=CodecRegistries.fromRegistries(MongoClient.getDefaultCodecRegistry(),CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        mongoCollection=mongoCollection.withCodecRegistry(pojoCodecRegistry);



           //mongodb.Article article = new mongodb.Article(new ObjectId(), "Welcome", "MaoJianGuo", "all", new Date(), new Date(), 1, "Welcome to our home,my friends,thanks for watching!");
          // mongoCollection.insertOne(article);

        /**Block<mongodb.Article> getAuthor=new Block<mongodb.Article>() {
            int i=1;
            public void apply(mongodb.Article article) {
                System.out.println(i+++" "+article.getAuthor());


            }
        };

        mongoCollection.find().projection(fields(include("author"),excludeId())).forEach(getAuthor);
*/

        Block<ChangeStreamDocument<Document>> printBlock=new Block<ChangeStreamDocument<Document>>() {
            @Override
            public void apply(ChangeStreamDocument<Document> documentChangeStreamDocument) {
                System.out.println(documentChangeStreamDocument);
            }
        };

        collection.watch(Arrays.asList(Aggregates.match(Filters.eq("author","MaoJianGuo")))).fullDocument(FullDocument.UPDATE_LOOKUP).forEach(printBlock);



        /**Document document=new Document("title","First article by Mao")
                .append("author","Mao")
                .append("article",new Document("date",new Date())
                .append("content","\t\tThis is my First mongodb.Article,Thanks for watching!\n\tI love MeiQi"))
                .append("keyword",Arrays.asList("Brief","all user","happy"));

        collection.insertOne(document);
        collection.aggregate(Arrays.asList(Aggregates.match(Filters.eq())))

        Document document1=collection.find(eq("author","Mao")).projection(fields(include("article.content"),excludeId())).first();
        System.out.println(""+document1.toJson());
*/
    }




    public static void insert(MongoCollection mongoCollection){
        //Create a Document
        Document doc = new Document("name", "MongoDB")
                .append("type", "database")
                .append("count", 1)
                .append("versions", Arrays.asList("v3.2", "v3.0", "v2.6"))
                .append("info", new Document("x", 203).append("y", 102));

        //Insert one Document
        mongoCollection.insertOne(doc);

        //Create the documents in a loop and add to the documents list
        List<Document> documents=new ArrayList<Document>();
        for(int i=0;i<100;i++){
            documents.add(new Document("i",i));
        }

        mongoCollection.insertMany(documents);

        System.out.println(mongoCollection.count());
    }

    public static void iterator(MongoCollection mongoCollection) {
        MongoCursor<Document> cursor=mongoCollection.find().iterator();
        try {
            while(cursor.hasNext()){
                System.out.println(cursor.next().toJson());
            }
        }finally {
            cursor.close();
        }
    }

    public static void getDocuments(MongoCollection mongoCollection){
        Block<Document> printBlock=new Block<Document>() {

            @Override
            public void apply(Document document) {
                System.out.println(document.toJson());
            }
        };

        mongoCollection.find(and(gt("i",20),lte("i",40))).forEach(printBlock);

    }

    public static void updateManys(MongoCollection mongoCollection){
        mongoCollection.updateOne(eq("i",10),new Document("$set",new Document("i",110)));
        UpdateResult updateResult=mongoCollection.updateMany(lt("i",100),inc("i",100));
        System.out.println(updateResult.getModifiedCount());
    }

    public static void createindex(MongoCollection mongoCollection){
        mongoCollection.createIndex(new Document("i",1));
    }

}
